<?php


namespace console\controllers;

use common\models\Book;
use common\models\Chapter;
use GuzzleHttp\Client;
use QL\QueryList;
use Yii;
use yii\base\InvalidConfigException;
use yii\console\Controller;
use yii\helpers\ArrayHelper;
use yii\helpers\Json;
use yii\helpers\StringHelper;

class SpiderController extends Controller
{
    public $domain = 'http://book.beiyinapp.com';
    public $header;
    public $cookie;

    public function actionIndex()
    {
        $this->grabList();
    }

    public function grabList()
    {
        $path = '/index/book/books.html';
        $url = "{$this->domain}{$path}";

        for ($page = 1; $page < 999; $page++) {

            echo "开始采集第{$page}页" . PHP_EOL;

            $ql = QueryList::getInstance()->get($url, ['page' => $page]);
            $data = Json::decode($ql->getHtml());

            if (ArrayHelper::getValue($data, 'status') != 0) {
                continue;
            }

            $list = ArrayHelper::getValue($data, 'data.list');

            if (empty($list) || !is_array($list)) {
                break;
            }

            foreach ($list as $item) {

                $book = Book::findOne(['title' => ArrayHelper::getValue($item, 'name')]);
                if (!$book) {
                    $book = new Book();
                    $book->title = ArrayHelper::getValue($item, 'name');
                    $book->desc = ArrayHelper::getValue($item, 'summary');
                    $book->image = $this->downloadImage(ArrayHelper::getValue($item, 'cover'));
                    $book->is_hot = Book::NOT_HOT;
                    $book->is_end = Book::NOT_END;
                    $book->status = Book::STATUS_ACTIVE;
                    $book->sort = 0;
                    $book->pid = 0;

                    if (!$book->save()) {
                        echo "保存书失败：{$book->getFirstErrors()[0]}";
                        continue;
                    }

                    echo "已采集{$book->title}" . PHP_EOL;
                }


                $params = parse_url(html_entity_decode(ArrayHelper::getValue($item, 'url')));

                parse_str(ArrayHelper::getValue($params, 'query'), $query_arr);

                $book_id = ArrayHelper::getValue($query_arr, 'book_id');

                $this->grabChapter($book_id, $book);
            }
        }

    }

    public function grabChapter($id, $book)
    {
        echo "开始采集章节：{$book->title}" . PHP_EOL;
        for ($i = 1; $i < 99999; $i++) {

            $chapter = Chapter::findOne(['book_id' => $book->id, 'number' => $i]);

            if (!$chapter) {
                $url = "{$this->domain}/index/book/read/{$id}/{$i}.html";
                $ql = QueryList::getInstance()->get($url);

                if ($ql->getHtml() == '章节不存在') {
                    break;
                }

                $title = $ql->find('.title')->html();
                $content = $ql->find('.content-raw')->html();

                $chapter = new Chapter();
                $chapter->book_id = $book->id;
                $chapter->number = $i;
                $chapter->title = $title;
                $chapter->content = $content;
                if(!$chapter->save()){
                    print_r($chapter->getFirstErrors());
                }

                echo "已采集第{$i}章" . PHP_EOL;
            }
        }


    }


    /**
     * @param $url
     * @return string
     * @throws InvalidConfigException
     */
    public function downloadImage($url)
    {
        $file_extension = pathinfo($url, PATHINFO_EXTENSION);

        $file_name = uniqid() . ".{$file_extension}";

        $relation_path = '/uploads/cover/' . date('Y-m-d') . '/';

        $absolutely_path = \Yii::$app->params['root'] . $relation_path;

        if (!file_exists($absolutely_path)) {
            if (!mkdir($absolutely_path, 0777, true)) {
                throw new InvalidConfigException('上传目录创建失败');
            }
        }

        $client = new Client();
        $response = $client->get($url, ['save_to' => $absolutely_path . $file_name]);

        if ($response->getStatusCode() == 200) {
            echo '下载封面图成功' . PHP_EOL;
        } else {
            echo '下载封面图失败' . PHP_EOL;
        }

        return $relation_path . $file_name;
    }
}